package entities.concept;

import java.util.HashSet;
import java.util.Set;

import entities.KBEntity;
import entities.role.Role;

public abstract class NaryConcept extends Concept {
	protected final HashSet<Concept> cons;

	protected NaryConcept() {
		this.cons = new HashSet<Concept>();
	}

	protected NaryConcept(Set<Concept> in) {
		this.cons = new HashSet<Concept>();
		this.cons.addAll(in);
	}

	// methods
	public Set<Concept> getConceptSet() {
		return this.cons;
	}

	// overriden ones
	
	public boolean hasUniversalInside(){
		for(Concept c:this.cons){
			if(c.hasUniversalInside()){
				return true;
			}
		}
		return false;
	}
	
	@Override
	public Concept getPrimeCopy() {
		Set<Concept> ns = new HashSet<Concept>();
		for (Concept c : this.cons) {
			ns.add(c.getPrimeCopy());
		}
		if (this instanceof AndConcept) {
			return new AndConcept(ns);
		} else if (this instanceof OrConcept) {
			return new OrConcept(ns);
		} else {
			return this;
		}
	}

	@Override
	public abstract String toSerializedString();

	@Override
	public Set<Role> extractFeatures() {
		Set<Role> fs = new HashSet<Role>();
		for (Concept d : this.cons) {
			fs.addAll(d.extractFeatures());
		}
		return fs;
	}

	@Override
	public Set<Role> extractRoles() {
		Set<Role> rs = new HashSet<Role>();
		for (Concept d : this.cons) {
			rs.addAll(d.extractRoles());
		}
		return rs;
	}

	@Override
	public Set<String> extractConstants() {
		Set<String> ks = new HashSet<String>();
		for (Concept c : this.cons) {
			ks.addAll(c.extractConstants());
		}
		return ks;
	}
	
	@Override 
	public Set<KBEntity> extractSig(){
		Set<KBEntity> sig = new HashSet<KBEntity>();
		for (Concept c : this.cons) {
			sig.addAll(c.extractSig());
		}
		return sig;
	}

	@Override
	public Set<AtomicConcept> extracAtomicConcepts() {
		Set<AtomicConcept> cs = new HashSet<AtomicConcept>();
		for (Concept c : this.cons) {
			if (c instanceof AtomicConcept) {
				cs.add((AtomicConcept) c);
			}
		}
		return cs;
	}

	@Override
	public boolean isParameterized() {
		for (Concept c : this.cons) {
			if (!c.isParameterized()) {
				return false;
			}
		}
		return true;
	}

	@Override
	public Concept makeParameterized() {
		Set<Concept> cs = new HashSet<Concept>();
		for (Concept c : this.cons) {
			cs.add(c.makeParameterized());
		}
		if (this instanceof AndConcept) {
			return new AndConcept(cs);
		} else if (this instanceof OrConcept) {
			return new OrConcept(cs);
		} else {
			return this;
		}
	}

	@Override
	public Concept initParameters(Role f, String v) {
		Set<Concept> cs = new HashSet<Concept>();
		for (Concept c : this.cons) {
			if (c.isParameterized()) {
				cs.add(c.initParameters(f, v));
			} else {
				cs.add(c);
			}
		}
		if (this instanceof AndConcept) {
			return new AndConcept(cs);
		} else if (this instanceof OrConcept) {
			return new OrConcept(cs);
		} else {
			return this;
		}
	}

}
